package com.yanjiali.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yanjiali.entity.CommentLike;
import com.yanjiali.feign.UserServiceFeign;
import com.yanjiali.model.R;
import com.yanjiali.model.req.AddCommentReq;
import com.yanjiali.model.req.DeleteCommentReq;
import com.yanjiali.model.req.PageGetCommentListByArticleIdReq;
import com.yanjiali.model.req.PageGetReplyByParentIdReq;
import com.yanjiali.model.resp.*;
import com.yanjiali.service.CommentLikeService;
import com.yanjiali.vo.CommentAndUserInfoAndReplyVO;
import com.yanjiali.vo.ReplyVO;
import com.yanjiali.model.GetLikeCommentListResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yanjiali.mapper.CommentMapper;
import com.yanjiali.entity.Comment;
import com.yanjiali.service.CommentService;

/**
 * @Package: com.yanjiali.service.impl
 * @Author: yanjiali
 * @Created: 2025/4/23 21:33
 * TODO 目前评论二级，三级后前端会自动优化，退步到二级
*/
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService{

    @Autowired
    private UserServiceFeign userServiceFeign;

    @Autowired
    private CommentLikeService commentLikeService;

    @Override
    public R<PageGetCommentListByArticleIdResp> queryTheCommentListByPageAccordingToTheArticleId(PageGetCommentListByArticleIdReq pageGetCommentListByArticleIdReq) {
        //设置分页参数
        Page<Comment> page = new Page();
        page.setCurrent(pageGetCommentListByArticleIdReq.getCurrent());
        page.setSize(pageGetCommentListByArticleIdReq.getSize());

        //构建条件构造器
        LambdaQueryWrapper<Comment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(pageGetCommentListByArticleIdReq.getArticleId() != null, Comment::getArticleId, pageGetCommentListByArticleIdReq.getArticleId())
                .isNull(Comment::getParentId)    //对应文章的评论且没有父评论
                .orderByDesc(Comment::getCreateTime);

        //查询
        Page<Comment> commentPage = page(page, lambdaQueryWrapper);

        //获取结果
        List<Comment> records = commentPage.getRecords();
        if(records != null && records.size() > 0) { //存在评论
            List<Long> userIdList = records.stream().map(comment -> comment.getUid()).collect(Collectors.toList());
            R<GetTheBasicInformationOfTheUserByIDsResp> feignRespR = userServiceFeign.getTheBasicInformationOfTheUserByIDs(userIdList);

            if(feignRespR.getCode() == 200) {
                List<CommentAndUserInfoAndReplyVO> commentAndUserInfoAndReplyVOList = new ArrayList<>();  //用于存储所需要展示的视图对象
                for(Comment comment : records) {
                    CommentAndUserInfoAndReplyVO commentAndUserInfoAndReplyVO = new CommentAndUserInfoAndReplyVO();

                    //TODO 封装第一层用户数据
                    Map<Long, GetTheBasicInformationOfTheUserByIDResp> userInfoMap = feignRespR.getData().getUserInfoList();
                    GetTheBasicInformationOfTheUserByIDResp userInfo = userInfoMap.get(comment.getUid());
                    commentAndUserInfoAndReplyVO.getUser().setUsername(userInfo.getUsername());
                    commentAndUserInfoAndReplyVO.getUser().setAvatar(userInfo.getAvatar());
                    commentAndUserInfoAndReplyVO.getUser().setLevel(userInfo.getLevel());

                    //TODO 封装第一层评论数据
                    commentAndUserInfoAndReplyVO.setId(comment.getId());
                    commentAndUserInfoAndReplyVO.setParentId(null);
                    commentAndUserInfoAndReplyVO.setUid(comment.getUid());
                    commentAndUserInfoAndReplyVO.setContent(comment.getContent());
                    commentAndUserInfoAndReplyVO.setCreateTime(comment.getCreateTime());

                    //TODO 封装回复数据
                    Long id = comment.getId();
                    R<PageGetReplyByParentIdResp> respR = pageGetReplyByParentId(new PageGetReplyByParentIdReq(1, 5, id));
                    if(respR.getCode() == 200) {  //获取到了对应的回复
                        ReplyVO reply = respR.getData().getReply();
                        commentAndUserInfoAndReplyVO.setReply(reply);
                    }

                    commentAndUserInfoAndReplyVOList.add(commentAndUserInfoAndReplyVO);
                }

                return R.ok(new PageGetCommentListByArticleIdResp(commentPage.getTotal(), commentAndUserInfoAndReplyVOList));
            }
        }

        return R.fail("当前文章没有对应评论");
    }

    @Override
    public R<PageGetReplyByParentIdResp> pageGetReplyByParentId(PageGetReplyByParentIdReq pageGetReplyByParentIdReq) {
        //设置分页参数
        Page<Comment> page = new Page<>();
        page.setCurrent(pageGetReplyByParentIdReq.getCurrent());
        page.setSize(pageGetReplyByParentIdReq.getSize());

        //构造条件构造器
        LambdaQueryWrapper<Comment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(pageGetReplyByParentIdReq.getParentId() != null, Comment::getParentId, pageGetReplyByParentIdReq.getParentId())
                .orderByDesc(Comment::getCreateTime);


        Page<Comment> commentPage = page(page, lambdaQueryWrapper);
        List<Comment> records = commentPage.getRecords();
        if(records != null && records.size() > 0) {
            //TODO 远程调用批量获取对应用户基本信息
            List<Long> userIdList = records.stream().map(comment -> comment.getUid()).collect(Collectors.toList());
            R<GetTheBasicInformationOfTheUserByIDsResp> respR = userServiceFeign.getTheBasicInformationOfTheUserByIDs(userIdList);
            if(respR.getCode() == 200) {
                // 封装对应回复评论所需的视图集合
                Map<Long, GetTheBasicInformationOfTheUserByIDResp> userInfoMap = respR.getData().getUserInfoList();
                ReplyVO replyVO = new ReplyVO();
                replyVO.setTotal(Long.valueOf(records.size())); //记录回复条数

                for (Comment reply : records) {
                    CommentAndUserInfoAndReplyVO commentAndUserInfoAndReplyVO = new CommentAndUserInfoAndReplyVO();
                    GetTheBasicInformationOfTheUserByIDResp userInfo = userInfoMap.get(reply.getUid());

                    //赋值用户基本信息
                    commentAndUserInfoAndReplyVO.getUser().setAvatar(userInfo.getAvatar());
                    commentAndUserInfoAndReplyVO.getUser().setLevel(userInfo.getLevel());
                    commentAndUserInfoAndReplyVO.getUser().setUsername(userInfo.getUsername());

                    //赋值评论信息
                    commentAndUserInfoAndReplyVO.setId(reply.getId());
                    commentAndUserInfoAndReplyVO.setAddress(userInfo.getAddress());
                    commentAndUserInfoAndReplyVO.setContent(reply.getContent());
                    commentAndUserInfoAndReplyVO.setCreateTime(reply.getCreateTime());
                    commentAndUserInfoAndReplyVO.setParentId(reply.getParentId());
                    commentAndUserInfoAndReplyVO.setUid(reply.getUid());
                    commentAndUserInfoAndReplyVO.setLikes(reply.getLikes());

                    //添加
                    replyVO.getList().add(commentAndUserInfoAndReplyVO);
                }

                return R.ok(new PageGetReplyByParentIdResp(replyVO));
            }
        }

        return R.fail("没有对应数据");
    }

    @Override
    public R<AddCommentResp> addComment(AddCommentReq addCommentReq) {
        //远程调用获取用户基本信息
        String userId = "";
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("用户未登录");
        }

        R<GetTheBasicInformationOfTheUserByIDResp> userInfoResp = userServiceFeign.getTheBasicInformationOfTheUserByID(Long.valueOf(userId));
        if (userInfoResp.getCode() == 200) {
            GetTheBasicInformationOfTheUserByIDResp userInfoRespData = userInfoResp.getData();
            Comment comment = new Comment();
            comment.setUid(Long.valueOf(userId));   //TODO 这里不是公共字段名
            comment.setAddress(userInfoRespData.getAddress());
            comment.setArticleId(addCommentReq.getArticleId());
            comment.setContent(addCommentReq.getContent());
            comment.setParentId(addCommentReq.getParentId());

            boolean save = save(comment);

            if(save) {
                //封装回传数据
                CommentAndUserInfoAndReplyVO commentAndUserInfoAndReplyVO = new CommentAndUserInfoAndReplyVO();
                commentAndUserInfoAndReplyVO.setId(comment.getId());
                commentAndUserInfoAndReplyVO.setParentId(null);
                commentAndUserInfoAndReplyVO.setUid(Long.valueOf(userId));
                commentAndUserInfoAndReplyVO.setContent(comment.getContent());
                commentAndUserInfoAndReplyVO.setCreateTime(comment.getCreateTime());
                //TODO 远程调用获取用户信息
                R<GetTheBasicInformationOfTheUserByIDResp> feignRespR = userServiceFeign.getTheBasicInformationOfTheUserByID(Long.valueOf(userId));
                if(feignRespR.getCode() == 200) {
                    GetTheBasicInformationOfTheUserByIDResp userInfo = feignRespR.getData();
                    commentAndUserInfoAndReplyVO.getUser().setUsername(userInfo.getUsername());
                    commentAndUserInfoAndReplyVO.getUser().setAvatar(userInfo.getAvatar());
                }
                return R.ok(new AddCommentResp(commentAndUserInfoAndReplyVO));
            }
        }

        return R.fail("评论失败");
    }

    @Override
    public R<DeleteCommentResp> deleteComment(DeleteCommentReq deleteCommentReq) {
        //获取登录用户的id
        String userId = "";
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("用户未登录");
        }

        //构造条件构造器
        LambdaUpdateWrapper<Comment> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper
                .eq(deleteCommentReq.getCommentId() != null, Comment::getId, deleteCommentReq.getCommentId())
                .eq("".equals(userId), Comment::getUid, userId);

        boolean remove = remove(lambdaUpdateWrapper);
        if(remove) {
            return R.ok(new DeleteCommentResp("删除成功"));
        }
        return R.fail("删除失败，网络错误或删除不属于自己的评论");
    }

    @Override
    public R<GetLikeCommentListResp> getLikeCommentList() {
        String userId = "";
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("用户未登录");
        }

        LambdaQueryWrapper<CommentLike> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CommentLike::getUid, userId);

        List<CommentLike> commentLikeList = commentLikeService.list(lambdaQueryWrapper);
        if(commentLikeList != null && commentLikeList.size() > 0) {
            List<Long> likeCommentIdList = commentLikeList
                    .stream()
                    .map(comment -> comment.getCommentId()).collect(Collectors.toList());

            return R.ok(new GetLikeCommentListResp(likeCommentIdList));
        }

        return R.fail("当前用户没有点赞评论数据");
    }
}
